home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
rpg
/
crossfir.92
/
crossfir
/
crossfire-0.92.5
/
server
/
gods.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-24
|
12KB
|
380 lines
/*
* static char *rcsid_apply_c =
* "$Id: gods.c,v 1.4 1996/07/24 07:37:10 master Exp master $";
*/
/*
CrossFire, A Multiplayer game for X-windows
Copyright (C) 1994 Mark Wedel
Copyright (C) 1992 Frank Tore Johansen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author can be reached via e-mail to mwedel@pyramid.com
*/
/* Oct 3, 1995 - Code laid down for initial gods, priest alignment, and
* monster race initialization. b.t.
*/
#include <global.h>
#include <living.h>
#include <object.h>
#include <spells.h>
#include <sounds.h>
#ifndef __CEXTRACT__
#include <sproto.h>
#endif
int
lookup_god_by_name(char *name) {
int godnr=0;
int nmlen = strlen(name);
if(name==NULL || !strcmp(name,"none")) return -1;
while(strncmp(name,Gods[godnr].name,MIN(strlen(Gods[godnr].name),nmlen))
&& godnr < (NROFGODS - 1)) {
godnr++;
}
if(godnr==NROFGODS) godnr=-1;
return godnr;
}
void become_follower (object *op, char *godname) {
object *exp_obj = op->chosen_skill->exp_obj;
int godnr = lookup_god_by_name(godname);
if(godnr<0) return;
new_draw_info_format(NDI_UNIQUE|NDI_NAVY,0,op,
"You become a follower of %s!",godname);
if(exp_obj->title) { /* get rid of old god */
new_draw_info_format(NDI_UNIQUE,0,op,
"%s's blessing is withdrawn from you.",exp_obj->title);
CLEAR_FLAG(exp_obj,FLAG_APPLIED);
(void) change_abil(op,exp_obj);
free_string(exp_obj->title);
}
/* now change to the new gods attributes to exp_obj */
exp_obj->title = add_string(godname);
exp_obj->protected=Gods[godnr].protected;
exp_obj->vulnerable=Gods[godnr].vulnerable;
exp_obj->path_attuned=Gods[godnr].path_attuned;
exp_obj->path_repelled=Gods[godnr].path_repelled;
exp_obj->path_denied=Gods[godnr].path_denied;
new_draw_info_format(NDI_UNIQUE,0,op,
"You are bathed in %s's aura.",godname);
SET_FLAG(exp_obj,FLAG_APPLIED);
(void) change_abil(op,exp_obj);
}
/* determine_god() - determines if op worships a god. Returns
* the godname if they do. In the case of an NPC, if they have
* no god, we give them a random one. -b.t.
*/
char *determine_god(object *op) {
int godnr = -1;
if(op->type!= PLAYER && !op->title && QUERY_FLAG(op,FLAG_ALIVE)) {
godnr = RANDOM()%NROFGODS;
return ((op->title = add_string(Gods[godnr].name)));
} else {
if((op->type==PLAYER && op->chosen_skill
&& op->chosen_skill->exp_obj && op->chosen_skill->exp_obj->title))
return op->chosen_skill->exp_obj->title;
}
return ("none");
}
/* god_intervention() - called from praying() currently. Every
* once in a while the god will intervene to help the worshiper.
* Later, this fctn can be used to supply quests, etc for the
* priest. -b.t.
*/
void god_intervention(object *op, char *godname) {
int godnr = lookup_god_by_name(godname);
int level=SK_level(op);
/*safety, shouldnt happen */
if(godnr==-1) return;
new_draw_info(NDI_UNIQUE|NDI_UNIQUE,0,op,"You feel a holy presence!");
/* So, what can we do to help out? We do some minimal checking
* of the god's attributes to ensure there is a bit of consistency
* between what happens and what the god can do. We do benefits
* in 2 sections. In the first, we check if the god can fix
* problems of the priest. In the second, rare boons are given.
* In either case, as soon as the god gives a gift, we return */
/* FIRST SECTION */
/* Restore the priest to a better state of grace. */
if(op->stats.grace<0) {
new_draw_info(NDI_UNIQUE,0,op,"You are returned to a state of grace.");
op->stats.grace=RANDOM()%10;
return;
}
/* Heal damage */
if(!(Gods[godnr].path_denied&PATH_RESTORE)) {
if(op->stats.hp<op->stats.maxhp) {
op->stats.hp=op->stats.maxhp;
new_draw_info(NDI_UNIQUE,0,op,"A white light surrounds and heals you!");
return;
}
}
/* cure confusion? */
if(!(Gods[godnr].attacktype&AT_CONFUSION))
if(cast_heal(op,0,SP_CURE_CONFUSION)) return;
/* remove poison? */
if(!(Gods[godnr].attacktype&AT_POISON))
if(cast_heal(op,0,SP_CURE_POISON)) return;
/* Remove cursed/damned items? This is better than the spell, here we
* allow unapplied items to be uncursed */
if(!(RANDOM()%2)&&!(Gods[godnr].path_denied&PATH_TURNING)) {
object *tmp;
int success = 0;
for (tmp = op->inv; tmp; tmp = tmp->below)
if (QUERY_FLAG(tmp, FLAG_CURSED)||QUERY_FLAG(tmp, FLAG_DAMNED)) {
success++;
if(QUERY_FLAG(tmp, FLAG_DAMNED)) CLEAR_FLAG(tmp, FLAG_DAMNED);
CLEAR_FLAG(tmp, FLAG_CURSED);
CLEAR_FLAG(tmp, FLAG_KNOWN_CURSED);
if (op->type == PLAYER && op->contr->eric_server > 0)
esrv_send_item(op, tmp);
}
if (op->type==PLAYER&&success) {
new_draw_info(NDI_UNIQUE, 0,op, "You feel like someone is helping you.");
draw_inventory(op);
return;
}
}
/* Fix drained stats? */
if(!(RANDOM()%2)&&!(Gods[godnr].attacktype&AT_DRAIN)) {
object *depl;
archetype *at;
if ((at = find_archetype("depletion"))==NULL) {
LOG(llevError,"Could not find archetype depletion");
return;
}
depl = present_arch_in_ob(at, op);
if (depl!=NULL) {
int i;
new_draw_info(NDI_UNIQUE,0,op,"Shimmering light surrounds and restores you!");
for (i = 0; i < 7; i++)
if (get_attr_value(&depl->stats, i)) {
new_draw_info(NDI_UNIQUE,0,op, restore_msg[i]);
}
remove_ob(depl);
free_object(depl);
fix_player(op);
return;
}
}
/* Special knowledge of the God? */
if((!RANDOM()%10)&&!(Gods[godnr].path_denied&PATH_INFO)) {
if(strcmp(Gods[godnr].enemy_race,"none")) {
new_draw_info_format(NDI_UNIQUE,0,op,
"You are filled with a desire to slay all things which are %s.",
Gods[godnr].enemy_race);
return;
} else if(strcmp(Gods[godnr].aligned_race,"none")) {
new_draw_info_format(NDI_UNIQUE,0,op,
"You are feel a bond with all things which are %s.",
Gods[godnr].aligned_race);
return;
}
}
/* SECOND SECTION */
/* Now, for the special section. If the priest is in a "state of grace"
* (ie grace.stats>100&&grace>maxgrace) we get one of the good benefits
* else, just a "super-blessing" via "holy possession" spell */
/* blessing via "holy possesion" spell */
if((op->stats.grace<80)||(op->stats.grace<op->stats.maxgrace)) {
(void) cast_change_attr(op,0,SP_HOLY_POSSESSION);
return;
}
/* Enchant/bless your weapon upto priest level/5 */
if(!(RANDOM()%2)&&QUERY_FLAG(op,FLAG_READY_WEAPON)) {
object *weapon=NULL;
for(weapon=op->inv;weapon;weapon=weapon->below)
if(weapon->type==WEAPON&&QUERY_FLAG(weapon,FLAG_APPLIED)) break;
/* allow the weapon to slay enemies */
if(weapon && !weapon->slaying&&strcmp("none",Gods[godnr].enemy_race)) {
char buf[MAX_BUF];
weapon->slaying = add_string(Gods[godnr].enemy_race);
new_draw_info(NDI_UNIQUE,0,op,"Your weapon quivers as if struck!");
if(!weapon->title) {
new_draw_info_format(NDI_UNIQUE,0,op,
"Your %s now hungers to slay enemies of your god!",
weapon->name);
sprintf(buf,"of %s",godname);
weapon->title=add_string(buf);
if(op->type==PLAYER) draw_inventory(op);
}
return;
}
/* add the gods attacktype*/
if(weapon && !(RANDOM()%2)&&!(weapon->attacktype&Gods[godnr].attacktype)) {
new_draw_info(NDI_UNIQUE,0,op,"Your weapon suddenly glows!");
weapon->attacktype=weapon->attacktype|Gods[godnr].attacktype;
return;
}
/* higher magic value */
if(weapon && !(RANDOM()%2)&&weapon->magic<(level/5)) {
new_draw_info(NDI_UNIQUE,0,op,
"A phosphorescent glow envelops your weapon!");
weapon->magic++;
if(op->type==PLAYER) draw_inventory(op);
return;
}
}
/* If they qualify, grant the priest use of a special spell */
if(op->stats.Wis&&op->stats.Wis>25) {
int spell=0;
/*generate a random rare clerical spell*/
do {
spell=RANDOM()%NROFREALSPELLS;
} while(spells[spell].books && !spells[spell].cleric);
/* The god will only teach the spell if its not against the nature
* of the cult, the priest is high enough in level *and* the priest
* doesnt already know it */
/* Also, there are some spells which can really disturb playbalance,
* to keep these out of player hands, we discard any spell which
* has PATH_NULL.
*/
if(!(Gods[godnr].path_denied&spells[spell].path)
&&!(Gods[godnr].path_repelled&spells[spell].path)
&&!(spells[spell].path&PATH_NULL)
&&spells[spell].level<=level
&&!check_spell_known(op,spell)) {
#ifdef SOUND_EFFECTS
play_sound_player_only(op->contr, SOUND_LEARN_SPELL);
#endif
new_draw_info_format(NDI_UNIQUE, 0,op,
"%s grants you use of a special prayer!",godname);
op->contr->known_spells[op->contr->nrofknownspells++]=spell;
if(op->contr->nrofknownspells == 1)
op->contr->chosen_spell=spell;
new_draw_info_format(NDI_UNIQUE, 0, op,
"Type 'bind cast %s",spells[spell].name);
new_draw_info(NDI_UNIQUE, 0,op,"to store the spell in a key.");
return;
}
}
/* Last message, sorry charlie, nothing was given except good vibes :) */
new_draw_info(NDI_UNIQUE, 0,op,"You feel rapture.");
}
/* get_god() - returns the gods index in Gods[] array, if the god
* exists, if not, it returns -1. -b.t.
*/
int get_god(object *priest) {
int godnr=lookup_god_by_name(determine_god(priest));
return godnr;
}
/* tailor_god_spell() - changes the attributes of cone, smite,
* and ball spells as needed by the code. Returns false if there
* was no race to assign to the slaying field of the spell, but
* the spell attacktype contains AT_HOLYWORD. -b.t.
*/
int tailor_god_spell(object *spellop, object *caster, int godnr) {
int caster_is_spell=0;
if(caster->type==FBULLET
||caster->type==CONE
||caster->type==FBALL) caster_is_spell=1;
if(!caster_is_spell)
if(godnr<0||((spellop->attacktype&AT_HOLYWORD)&&
!strcmp(Gods[godnr].enemy_race,"none"))) {
new_draw_info(NDI_UNIQUE, 0, caster,
"This prayer is useless unless you worship an appropriate god");
free_object(spellop);
return 0;
}
/* either holy word or godpower attacks will set the slaying field */
if(spellop->attacktype&AT_HOLYWORD||spellop->attacktype&AT_GODPOWER) {
if(spellop->slaying) free_string(spellop->slaying);
if(!caster_is_spell)
spellop->slaying = add_string(Gods[godnr].enemy_race);
else if(caster->slaying)
spellop->slaying = add_string(caster->slaying);
}
/* only the godpower attacktype adds the god's attack onto the spell */
if((spellop->attacktype&AT_GODPOWER)&&!caster_is_spell)
spellop->attacktype=spellop->attacktype|Gods[godnr].attacktype;
/* a little cosmetic for fun, we tack on the god's name to the spell */
if(spellop->attacktype&AT_HOLYWORD||spellop->attacktype&AT_GODPOWER) {
if(spellop->title) free_string(spellop->title);
if(caster_is_spell&&caster->title)
spellop->title=add_string(caster->title);
else if((godnr=get_god(caster))!=-1)
spellop->title=add_string(Gods[godnr].name);
if(spellop->title){
char buf[MAX_BUF];
sprintf(buf,"%s of %s",spellop->name,spellop->title);
spellop->name=add_string(buf);
}
}
return 1;
}